using System;
using NUnit.Framework;
using RunAllTestsInSolutionTask;
using System.IO;

namespace RunAllTestsInSolutionTaskTests
{
    [TestFixture]
    class ManagedProjectParserTests : BaseProjectParserTests
    {
        private const string MANAGED_CPP_PRODUCTION_PROJECT = @"TestData\Conversions\Implementation\Conversions\Conversions.vcxproj";
        private const string CPP_PRODUCTION_DEBUG_DLL_FILE = @"TestData\Conversions\Test\ConversionsTest\..\..\..\..\UnitTest\Indigo.iPC.Foundations.Conversions.ConversionsTest.dll";


        protected const string MANAGED_CPP_TEST_PROJECT_FILE = @"TestData\Conversions\Test\ConversionsTest\ConversionsTest.vcxproj";
        private const string RUN_ALL_TESTS_DEBUG_DLL_FILE = @"TestData\Conversions\Test\ConversionsTest\..\..\..\..\UnitTest\Indigo.iPC.Foundations.Conversions.ConversionsTest.dll";
        private const string RUN_ALL_TESTS_RELEASE_DLL_FILE = @"TestData\Conversions\Test\ConversionsTest\..\..\..\..\UnitTest\Indigo.iPC.Foundations.Conversions.ConversionsTest.dll";

        private const string EXE_PROJECT_NO_CHANGES_BY_USER = @"TestData\ManagedCPPProjects\ManagedSimpleExe.vcxproj";
        private const string EXE_PROJECT_NO_CHANGES_BY_USER_OUTPUT_FILENAME =
            @"TestData\Debug\ManagedSimpleExe.exe";
        private const string EXE_PROJECT_NO_CHANGES_BY_USER_RELEASE_OUTPUT_FILENAME =
            @"TestData\Release\ManagedSimpleExe.exe";

        private const string EXE_PROJECT_OUTDIR_SET_BY_USER = @"TestData\ManagedCPPProjects\ManagedSimpleExeCustomDir.vcxproj";
        private const string EXE_PROJECT_OUTDIR_SET_BY_USER_OUTPUT_FILENAME =
            @"TestData\ManagedCPPProjects\CustomDir\ManagedSimpleExeCustomDir.exe";

        private const string EXE_PROJECT_TARGETNAME_SET_BY_USER = @"TestData\ManagedCPPProjects\ManagedSimpleExeCustomTarget.vcxproj";
        private const string EXE_PROJECT_TARGETNAME_SET_BY_USER_OUTPUT_FILENAME =
            @"TestData\Debug\CustomTarget.exe";

        private const string EXE_PROJECT_OUTPUTFILE_SET_BY_USER = @"TestData\ManagedCPPProjects\ManagedSimpleExeCustomFile.vcxproj";
        private const string EXE_PROJECT_OUTPUTFIL_SET_BY_USER_OUTPUT_FILENAME =
            @"TestData\ManagedCPPProjects\CustomFile.exe";


        [Test]
        public void IsTestProject_GivenNativeCPPProductionProject_ReturnsFalse()
        {
            var target = new ManagedProjectParser(MANAGED_CPP_PRODUCTION_PROJECT);
            var actual = target.IsTestProject();
            Assert.IsFalse(actual);
        }

        [Test]
        public void IsTestProject_GivenNativeCPPTestProject_ReturnsTrue()
        {
            var target = new ManagedProjectParser(MANAGED_CPP_TEST_PROJECT_FILE);
            var actual = target.IsTestProject();
            Assert.IsTrue(actual);
        }


        [Test]
        public void GetOutputDll_ForDebug_ReturnsDebugDllName()
        {
            var target = new ManagedProjectParser(MANAGED_CPP_TEST_PROJECT_FILE);

            var dllName = target.GetOutputFile("Debug");

            Assert.AreEqual(RUN_ALL_TESTS_DEBUG_DLL_FILE, dllName);
        }


        [Test]
        public void GetOutputDll_ForRelease_ReturnsReleaseDllName()
        {
            var target = new ManagedProjectParser(MANAGED_CPP_TEST_PROJECT_FILE);

            var dllName = target.GetOutputFile("Release");

            Assert.AreEqual(RUN_ALL_TESTS_RELEASE_DLL_FILE, dllName);
        }

        [Test]
        [Ignore("not yet supported vraibels inside variables")]
        public void GetOutputDll_ProductionProject_CorrectFile()
        {
            //does not support this 
            var target = new ManagedProjectParser(MANAGED_CPP_PRODUCTION_PROJECT);

            var dllName = target.GetOutputFile("Debug");

            Assert.AreEqual(CPP_PRODUCTION_DEBUG_DLL_FILE, dllName);
        }


        
        [Test]
        public void GetOutputDll_DefaultProject_LocationInDebugDirUnderSolution()
        {
            //default values are in solutiondir\$(configuration)\
            var target = new ManagedProjectParser(EXE_PROJECT_NO_CHANGES_BY_USER);

            var dllName = target.GetOutputFile("Debug");
            
            var expected = Path.GetFullPath(EXE_PROJECT_NO_CHANGES_BY_USER_OUTPUT_FILENAME);
            var actual = Path.GetFullPath(dllName);
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void GetOutputDll_DefaultProjectReleaseConfiguration_LocationInReleaseDirUnderSolution()
        {
            var target = new ManagedProjectParser(EXE_PROJECT_NO_CHANGES_BY_USER);

            var dllName = target.GetOutputFile("Release");

            var expected = Path.GetFullPath(EXE_PROJECT_NO_CHANGES_BY_USER_RELEASE_OUTPUT_FILENAME);
            var actual = Path.GetFullPath(dllName);
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void GetOutputDll_WhenUserSetTargetFile_ReturnsNameAccordingToTarget()
        {
            var target = new ManagedProjectParser(EXE_PROJECT_TARGETNAME_SET_BY_USER);

            var dllName = target.GetOutputFile("Debug");

            var expected = Path.GetFullPath(EXE_PROJECT_TARGETNAME_SET_BY_USER_OUTPUT_FILENAME);
            var actual = Path.GetFullPath(dllName);
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void GetOutputDll_WhenUserSetOutdir_ReturnsLocationaccordingtoOutdir()
        {
            //user changed the outdir (only) so we reflect the outdir location into the output file
            var target = new ManagedProjectParser(EXE_PROJECT_OUTDIR_SET_BY_USER);

            var dllName = target.GetOutputFile("Debug");

            var expected = Path.GetFullPath(EXE_PROJECT_OUTDIR_SET_BY_USER_OUTPUT_FILENAME);
            var actual = Path.GetFullPath(dllName);
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void GetOutputDll_WhenUserSetOutPutfile_ReturnsLocationOfOutputFile()
        {

            var target = new ManagedProjectParser(EXE_PROJECT_OUTPUTFILE_SET_BY_USER);

            var dllName = target.GetOutputFile("Debug");

            var expected = Path.GetFullPath(EXE_PROJECT_OUTPUTFIL_SET_BY_USER_OUTPUT_FILENAME);
            var actual = Path.GetFullPath(dllName);
            Assert.AreEqual(expected, actual);
        }
    }
}
